/*
 * @Author: hongbin
 * @Date: 2023-08-27 11:34:41
 * @LastEditors: hongbin
 * @LastEditTime: 2023-10-01 14:36:27
 * @Description:
 */
import { ThreeHelper } from "..";
import { Vector3 } from "three";

/**
 * 类装饰器
 * 相机注入
 * 接收类需要声明
 * private camera!: THREE.PerspectiveCamera;
 * private cameraWrapper!: THREE.Object3D;
 */
export function CameraInject(constructor) {
    return class extends constructor {
        camera = ThreeHelper.instance.camera;
        cameraWrapper = ThreeHelper.instance.camera.parent;
    };
}

const defaultParams = {
    addAxis: true,
    useRoomLight: true,
    useLegacyLights: true,
    cameraPosition: new Vector3(0, 0, 10),
    near: 0.01,
    far: 1000,
    pixelRatio: undefined,
};

/**
 * 方法装饰器 - 基础环境参数设置
 */
export const MethodBaseSceneSet = (params) => {
    return function (target, _, description) {
        const prev = description.value;
        description.value = function () {
            try {
                const realParams = { ...defaultParams, ...params };
                const helper = this.helper;
                helper.addStats();
                realParams.addAxis && helper.addAxis();
                // helper.renderer.useLegacyLights = true;
                helper.camera.position.copy(realParams.cameraPosition);
                helper.frameByFrame();
                helper.addGUI();
                realParams.useRoomLight && helper.useRoomEnvironment();
                realParams.near && (helper.camera.near = realParams.near);
                realParams.far && (helper.camera.far = realParams.far);
                if (realParams.near || realParams.far)
                    helper.camera.updateProjectionMatrix();
                realParams.pixelRatio &&
                    helper.renderer.setPixelRatio(realParams.pixelRatio);
                prev.call(this);
            } catch (error) {
                throw error;
            }
        };
    };
};

/**
 * 方法装饰器 - gltf加载装饰器
 */
export const LoadGLTF = (url) => {
    if (!url) throw new Error("url 为空");
    return (_, __, description) => {
        const prev = description.value;
        // 不能使用尖头函数 会导致函数内部的this偏离
        description.value = function () {
            ThreeHelper.instance.loadGltf(url).then((gltf) => {
                gltf && prev.call(this, gltf);
            });
        };
    };
};

export function EveryFrame(target, _, description) {
    const prev = description.value;
    description.value = function () {
        this.helper.animation(() => {
            prev.call(this);
        })
    };
}